package com.atguigu.lease.web.admin.service.impl;

import com.atguigu.lease.common.exception.LeaseException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import com.atguigu.lease.model.entity.*;
import com.atguigu.lease.model.enums.ItemType;
import com.atguigu.lease.model.enums.ReleaseStatus;
import com.atguigu.lease.web.admin.mapper.ApartmentInfoMapper;
import com.atguigu.lease.web.admin.service.*;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentDetailVo;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentItemVo;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentQueryVo;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentSubmitVo;
import com.atguigu.lease.web.admin.vo.fee.FeeValueVo;
import com.atguigu.lease.web.admin.vo.graph.GraphVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.val;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author liubo
 * @description 针对表【apartment_info(公寓信息表)】的数据库操作Service实现
 * @createDate 2023-07-24 15:48:00
 */
@Service
@Transactional
public class ApartmentInfoServiceImpl extends ServiceImpl<ApartmentInfoMapper, ApartmentInfo>
        implements ApartmentInfoService {
    @Autowired
    private ApartmentFacilityService apartmentFacilityService;
    @Autowired
    private ApartmentFeeValueService apartmentFeeValueService;
    @Autowired
    private ApartmentLabelService   apartmentLabelService;
    @Autowired
    private GraphInfoService graphInfoService;
    @Autowired
    private ApartmentInfoMapper apartmentInfoMapper;
    @Autowired
    private LabelInfoService labelInfoService;
    @Autowired
    private FeeValueService feeValueService;
    @Autowired
    private RoomInfoService roomInfoService;
    @Override
    public void saveOrUpdateApartment(ApartmentSubmitVo apartmentSubmitVo) {

        Long apartmentId0=apartmentSubmitVo.getId();
        boolean updateFlag= apartmentId0 !=null&& apartmentId0!=0;
    //1.保存或更新ApartmentInfo自身的信息（insert或update apartmentInfo表）
        super.saveOrUpdate(apartmentSubmitVo);


        //2.如果是更新，则需要先删除之前的关系信息
        if(updateFlag){
            /**

            //2.1删除和配套之间的关系
            apartmentSubmitVo.getFacilityInfoIds().forEach(facilityId->{
                apartmentFacilityService.remove(new LambdaQueryWrapper<ApartmentFacility>().
                        eq(ApartmentFacility::getApartmentId,facilityId)
                        .eq(ApartmentFacility::getApartmentId,apartmentId));

            });
             * **/

            apartmentFacilityService.remove(new LambdaQueryWrapper<ApartmentFacility>().eq(ApartmentFacility::getApartmentId,apartmentId0));

            //2.2删除和标签之间的关系
            apartmentLabelService.remove(new LambdaQueryWrapper<ApartmentLabel>().eq(ApartmentLabel::getApartmentId,apartmentId0));
            //2.3删除和杂费之间的关系
            apartmentFeeValueService.remove(new LambdaQueryWrapper<ApartmentFeeValue>().eq(ApartmentFeeValue::getApartmentId,apartmentId0));
            //2.4删除之前的照片
            graphInfoService.remove(new LambdaQueryWrapper<GraphInfo>().eq(GraphInfo::getItemId,apartmentId0).eq(GraphInfo::getItemType,ItemType.APARTMENT));

        }






    //2.保存公寓的关系信息（和配套的关系，和杂费的关系，和标签的关系，和图片的关系）/
        // 3.1保存和配套的关系信息
        Long apartmentId=apartmentSubmitVo.getId();
        apartmentSubmitVo.getFacilityInfoIds().stream().map(facilityId->new ApartmentFacility(apartmentId,facilityId))
                .forEach(apartmentFacilityService::saveOrUpdate);


        //3.2 保存和杂费的关系信息
        apartmentSubmitVo.getFeeValueIds().stream().map(feeValueId->new ApartmentFeeValue(apartmentId,feeValueId))
                .forEach(apartmentFeeValueService::saveOrUpdate);


        //3.3保存和标签的关系信息
        apartmentSubmitVo.getFeeValueIds().stream().map(labelId-> ApartmentLabel.builder().apartmentId(apartmentId).labelId(labelId).build())
                .forEach(apartmentLabelService::saveOrUpdate);

        //3.4保存图片信息

        apartmentSubmitVo.getGraphVoList().forEach(graphVo -> {
            GraphInfo graphInfo=new GraphInfo();
            BeanUtils.copyProperties(graphVo,graphInfo);
            graphInfo.setItemType(ItemType.APARTMENT);
            graphInfo.setItemId(apartmentId);
        });
    }

    @Override
    public void pageApartmentItemByQuery(IPage<ApartmentItemVo> page,ApartmentQueryVo queryVo) {
        apartmentInfoMapper.pageApartmentItemByQuery(page,queryVo);
    }

    @Override
    public ApartmentDetailVo getApartmentDetail(Long apartmentId) {


        //业务方法：获取公寓详情，应该包含如下五个动作
        //1.获取公寓基本信息
        ApartmentInfo apartmentInfo = getById(apartmentId);
        if (apartmentInfo!=null) {
            //2.获取公寓的配套信息
            List<FacilityInfo> facilityList = apartmentFacilityService.getApartmentFaciltyListByApartmentId(apartmentId);
            //3.获取公寓的标签信息
            List<LabelInfo> labelInfoList = labelInfoService.getLabelInfoListByApartmentId(apartmentId);
            //4.获取公寓的杂费信息
            List<FeeValueVo> feeValueList = feeValueService.getFeeValueListByApartmentId(apartmentId);
            //5.获取公寓的图片信息
            List<GraphInfo> graphInfoList = graphInfoService.list(new LambdaQueryWrapper<GraphInfo>().eq(GraphInfo::getItemType,ItemType.APARTMENT)
                    .eq(GraphInfo::getItemId,apartmentId));


            ApartmentDetailVo apartmentDetailVo = new ApartmentDetailVo();
            BeanUtils.copyProperties(apartmentInfo,apartmentDetailVo);
            apartmentDetailVo.setFacilityInfoList(facilityList);
            apartmentDetailVo.setLabelInfoList(labelInfoList);
            apartmentDetailVo.setFeeValueVoList(feeValueList);
            apartmentDetailVo.setGraphVoList(graphInfoList.stream().map(graphInfo -> GraphVo.builder().name(graphInfo.getName()).url(graphInfo.getUrl()).build()).collect(Collectors.toList()));

            return apartmentDetailVo;
        }
            return null;
    }

    @Override

    public void removeApartmentById(Long id) {

      if (roomInfoService.count(new LambdaQueryWrapper<RoomInfo>().eq(RoomInfo::getApartmentId,id))>0){

          throw new LeaseException(ResultCodeEnum.DELETE_ERROR);
      }


          // 删除公寓本身的信息

        super.removeById(id);
        //删除这个公寓关联的信息，配套，标签，杂费，图片
        //配套（删除的是中间表中的记录）
        apartmentFacilityService.remove(new LambdaQueryWrapper<ApartmentFacility>().eq(ApartmentFacility::getApartmentId,id));

        //标签
        apartmentLabelService.remove(new LambdaQueryWrapper<ApartmentLabel>().eq(ApartmentLabel::getApartmentId,id));
        //杂费
        apartmentFeeValueService.remove(new LambdaQueryWrapper<ApartmentFeeValue>().eq(ApartmentFeeValue::getApartmentId,id));
        //图片（删除的是图片表）
        graphInfoService.remove(new LambdaQueryWrapper<GraphInfo>().eq(GraphInfo::getItemType,ItemType.APARTMENT).eq(GraphInfo::getItemId,id));





    }

    @Override
    public void updateStatus(Long id,ReleaseStatus status) {
        super.update(new LambdaUpdateWrapper<ApartmentInfo>().eq(ApartmentInfo::getId,id).set(ApartmentInfo::getIsRelease,status));
    }

}




